package com.hunt.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hunt.dao.NorthBoundStocksMapper;
import com.hunt.model.entity.NorthBoundStockClassify;
import com.hunt.model.entity.NorthBoundStocks;
import com.hunt.model.entity.NorthCrawler;
import com.hunt.model.entity.NorthCapitalHoldingsRank;
import com.hunt.service.AppNorthCrawlerService;
import com.hunt.util.SeasonEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class AppNorthCrawlerServiceImpl implements AppNorthCrawlerService {


    @Autowired
    private MongoTemplate northFundMongoTemplate;
    @Autowired
    private MongoTemplate northFundHigestTemplate;
    @Autowired
    private MongoTemplate northFundReverseBuyTemplate;
    @Autowired
    private MongoTemplate northFundStillBuyTemplate;
    @Autowired
    private MongoTemplate northFundHistoryTemplate;
    @Resource
    private RedisTemplate stringredisTemplate;
    @Resource
    private RedisTemplate redisTemplate;
    @Autowired
    private NorthBoundStocksMapper northBoundStocksMapper;

    @Override
    public NorthCrawler getNewNorthCrawler() {
        Query query = new Query();
        query.with(new Sort(Sort.Direction.DESC,"_id")).limit(1);
        return northFundMongoTemplate.findOne(query,NorthCrawler.class,"northCrawler");
    }

    @Override
    public List<NorthCrawler> getAllNorthCrawler() {
        Query query = new Query();query.with(new Sort(Sort.Direction.ASC,"_id"));
        return northFundMongoTemplate.find(query,NorthCrawler.class,"northCrawler");
    }

    @Override
    public List<NorthBoundStocks> getNorthStocks(String order, Integer position, Integer size) {
        order = order.equals("0")?"desc":"asc";
        return northBoundStocksMapper.getNorthStocks(order,position,size);
    }

    @Override
    public List<NorthBoundStocks> getNorthStocksThree(String order, Integer position, Integer size) {
        order = order.equals("0")?"desc":"asc";
        return northBoundStocksMapper.getNorthStocksThree(order,position,size);
    }

    @Override
    public List<NorthBoundStocks> getNorthStocksFive(String order, Integer position, Integer size) {
        order = order.equals("0")?"desc":"asc";
        return northBoundStocksMapper.getNorthStocksFive(order,position,size);
    }

    @Override
    public List<NorthBoundStocks> getNorthStocksTen(String order, Integer position, Integer size) {
        order = order.equals("0")?"desc":"asc";
        return northBoundStocksMapper.getNorthStocksTen(order,position,size);
    }

    @Override
    public List<NorthBoundStocks> getNorthStocksMonth(String order, Integer position, Integer size) {
        order = order.equals("0")?"desc":"asc";
        return northBoundStocksMapper.getNorthStocksMonth(order,position,size);
    }

    @Override
    public List<NorthCapitalHoldingsRank> getNorthHoldingsRank(String rankId, Integer position, Integer size) {
        rankId = rankId.equals("0")?"desc":"asc";
        String orderId = rankId == "desc"?"1":"0";
//        String orderId = null;
//        if(rankId == "desc"){
//            orderId = "1";
//        } else {
//            orderId = "0";
//        }

        return northBoundStocksMapper.getNorthHoldingsRank(orderId,rankId,position,size);
    }

    @Override
    public List<NorthCapitalHoldingsRank> getNorthRank3day(String rankId, Integer position, Integer size) {
        rankId = rankId.equals("0")?"desc":"asc";
        String orderId = rankId == "desc"?"1":"0";
        return northBoundStocksMapper.getNorthRank3day(orderId,rankId,position,size);
    }

    @Override
    public List<NorthBoundStockClassify> getNorthHigest(String date,String orederfield,String sort) {
        List<NorthBoundStockClassify> ln=northFundHigestTemplate.find(new Query(),NorthBoundStockClassify.class,date);
        //为历史数据补充实时
        getRealTimeData(ln);
        if(orederfield.equals("shareholddate")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholddate));
        }
        if(orederfield.equals("zdlimit")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getZdlimit));
        }
        if(orederfield.equals("newprice")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getNewprice));
        }
        if(orederfield.equals("shareholdamount")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdamount));
        }
        if(orederfield.equals("shareholdvalue")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdvalue));
        }
        if(orederfield.equals("shareholdpercent")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdpercent));
        }
        if(orederfield.equals("money")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getMoney));
        }
        if(orederfield.equals("qrr")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getQrr));
        }
        if(orederfield.equals("handchange")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getHandchange));
        }
        if(orederfield.equals("pe")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getPe));
        }
        if(orederfield.equals("stockname")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getStockname));
        }
        if(orederfield.equals("stockcode")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getStockcode));
        }
        if("0".equals(sort)){
            Collections.reverse(ln);
        }
      return ln;
    }
    @Override
    public List<NorthBoundStockClassify> getNorthReverseBuy(String date,String orederfield,String sort) {
        List<NorthBoundStockClassify> ln=northFundReverseBuyTemplate.find(new Query(),NorthBoundStockClassify.class,date);
        //为历史数据补充实时
        getRealTimeData(ln);
        if(orederfield.equals("shareholddate")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholddate));
        }
        if(orederfield.equals("zdlimit")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getZdlimit));
        }
        if(orederfield.equals("newprice")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getNewprice));
        }
        if(orederfield.equals("shareholdamount")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdamount));
        }
        if(orederfield.equals("shareholdvalue")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdvalue));
        }
        if(orederfield.equals("shareholdpercent")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdpercent));
        }
        if(orederfield.equals("money")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getMoney));
        }
        if(orederfield.equals("qrr")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getQrr));
        }
        if(orederfield.equals("handchange")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getHandchange));
        }
        if(orederfield.equals("pe")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getPe));
        }
        if(orederfield.equals("stockname")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getStockname));
        }
        if(orederfield.equals("stockcode")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getStockcode));
        }
        if("0".equals(sort)){
            Collections.reverse(ln);
        }
        return ln;
    }

    @Override
    public List<NorthBoundStockClassify> getNorthStillAdd(String date,String orederfield,String sort) {
        List<NorthBoundStockClassify> ln=northFundStillBuyTemplate.find(new Query(),NorthBoundStockClassify.class,date);
        //为历史数据补充实时
        getRealTimeData(ln);
        if(orederfield.equals("shareholddate")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholddate));
        }
        if(orederfield.equals("zdlimit")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getZdlimit));
        }
        if(orederfield.equals("newprice")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getNewprice));
        }
        if(orederfield.equals("shareholdamount")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdamount));
        }
        if(orederfield.equals("shareholdvalue")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdvalue));
        }
        if(orederfield.equals("shareholdpercent")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdpercent));
        }
        if(orederfield.equals("money")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getMoney));
        }
        if(orederfield.equals("qrr")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getQrr));
        }
        if(orederfield.equals("handchange")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getHandchange));
        }
        if(orederfield.equals("pe")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getPe));
        }
        if(orederfield.equals("stockname")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getStockname));
        }
        if(orederfield.equals("stockcode")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getStockcode));
        }
        if("0".equals(sort)){
            Collections.reverse(ln);
        }
        return ln;
    }

    @Override
    public List<NorthBoundStockClassify> getNorthHigestLatest(String date,String orederfield,String sort) {
        Set<String> ss=northFundHigestTemplate.getCollectionNames();
        List<String> list = new ArrayList<>(ss);
        Collections.sort(list);
        date=list.get(list.size()-1);
        List<NorthBoundStockClassify> ln=northFundHigestTemplate.find(new Query(),NorthBoundStockClassify.class,date);
        //为历史数据补充实时
        getRealTimeData(ln);
        if(orederfield.equals("shareholddate")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholddate));
        }
        if(orederfield.equals("zdlimit")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getZdlimit));
        }
        if(orederfield.equals("newprice")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getNewprice));
        }
        if(orederfield.equals("shareholdamount")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdamount));
        }
        if(orederfield.equals("shareholdvalue")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdvalue));
        }
        if(orederfield.equals("shareholdpercent")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdpercent));
        }
        if(orederfield.equals("money")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getMoney));
        }
        if(orederfield.equals("qrr")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getQrr));
        }
        if(orederfield.equals("handchange")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getHandchange));
        }
        if(orederfield.equals("pe")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getPe));
        }
        if(orederfield.equals("stockname")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getStockname));
        }
        if(orederfield.equals("stockcode")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getStockcode));
        }
        if("0".equals(sort)){
            Collections.reverse(ln);
        }
        return ln;
    }

    @Override
    public List<NorthBoundStockClassify> getNorthReverseBuyLatest(String date,String orederfield,String sort) {
        Set<String> ss=northFundReverseBuyTemplate.getCollectionNames();
        List<String> list = new ArrayList<>(ss);
        Collections.sort(list);
        date=list.get(list.size()-1);
        List<NorthBoundStockClassify> ln=northFundReverseBuyTemplate.find( new Query(),NorthBoundStockClassify.class,date);
        //为历史数据补充实时
        getRealTimeData(ln);
        if(orederfield.equals("shareholddate")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholddate));
        }
        if(orederfield.equals("zdlimit")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getZdlimit));
        }
        if(orederfield.equals("newprice")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getNewprice));
        }
        if(orederfield.equals("shareholdamount")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdamount));
        }
        if(orederfield.equals("shareholdvalue")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdvalue));
        }
        if(orederfield.equals("shareholdpercent")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdpercent));
        }
        if(orederfield.equals("money")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getMoney));
        }
        if(orederfield.equals("qrr")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getQrr));
        }
        if(orederfield.equals("handchange")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getHandchange));
        }
        if(orederfield.equals("pe")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getPe));
        }
        if(orederfield.equals("stockname")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getStockname));
        }
        if(orederfield.equals("stockcode")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getStockcode));
        }
        if("0".equals(sort)){
            Collections.reverse(ln);
        }
        return ln;
    }

    @Override
    public List<NorthBoundStockClassify> getNorthStillAddLatest(String date,String orederfield,String sort) {
        Set<String> ss=northFundStillBuyTemplate.getCollectionNames();
        List<String> list = new ArrayList<>(ss);
        Collections.sort(list);
        date=list.get(list.size()-1);
        List<NorthBoundStockClassify> ln=northFundStillBuyTemplate.find( new Query(),NorthBoundStockClassify.class,date);
        //为历史数据补充实时
        getRealTimeData(ln);
        if(orederfield.equals("shareholddate")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholddate));
        }
        if(orederfield.equals("zdlimit")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getZdlimit));
        }
        if(orederfield.equals("newprice")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getNewprice));
        }
        if(orederfield.equals("shareholdamount")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdamount));
        }
        if(orederfield.equals("shareholdvalue")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdvalue));
        }
        if(orederfield.equals("shareholdpercent")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getShareholdpercent));
        }
        if(orederfield.equals("money")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getMoney));
        }
        if(orederfield.equals("qrr")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getQrr));
        }
        if(orederfield.equals("handchange")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getHandchange));
        }
        if(orederfield.equals("pe")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getPe));
        }
        if(orederfield.equals("stockname")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getStockname));
        }
        if(orederfield.equals("stockcode")){
            Collections.sort(ln,Comparator.comparing(NorthBoundStockClassify::getStockcode));
        }
        if("0".equals(sort)){
            Collections.reverse(ln);
        }
        return ln;
    }

    @Override
    public List<NorthBoundStockClassify> getNorthHistory(String code) {
        Query query=new Query();
        query.with(new Sort(Sort.Direction.ASC, "shareholddate"));
        return northFundHistoryTemplate.find(query,NorthBoundStockClassify.class,code);
    }
    void getRealTimeData(List<NorthBoundStockClassify> ln){
        for(NorthBoundStockClassify nc:ln){
            Object obj = stringredisTemplate.opsForHash().get("Real_time_Stock_Data",nc.getStockcode());
            JSONObject jo = JSON.parseObject((String) obj);
            Object obj2 = stringredisTemplate.opsForHash().get("Stock_Base_Message",nc.getStockcode());
            JSONObject jo2 = JSON.parseObject((String) obj2);
            double newprice = 0.0;
            double  preclose = 0.0;
            double openprice = 0.0;
            double money = 0.0;
            double qrr = 0.0;
            double zdlimit = 0.0;
            double  floatsharesstock  = 0.0;
            double  handchange = 0.0;
            double totalsharestock = 0.0;
            double mv = 0.0;
            double vol = 0.0;
            try {
                newprice = jo.getDouble("newPrice");
            } catch (Exception e) {

            }
            try {
                preclose = jo.getDouble("preClose");
            } catch (Exception e) {

            }
            try {
                openprice = jo.getDouble("open");
            } catch (Exception e) {

            }
            try {
               money = jo.getDouble("money");
            } catch (Exception e) {
            }
            try {
                qrr = jo.getDouble("qrr");
            } catch (Exception e) {
            }
            try {
                vol = jo.getDouble("vol");
            } catch (Exception e) {
            }
            try {
                floatsharesstock = jo2.getDouble("floatShares")* 10000;
            } catch (Exception e) {
            }
            if (preclose != 0){
                zdlimit = ((newprice - preclose) / preclose) * 100;
            }

            if (floatsharesstock != 0){
                handchange = (vol * 10000 / floatsharesstock);
            }
            try {
                if (jo2.getFloat("totalShares") != null) {
                    totalsharestock = jo2.getDouble("totalShares")*10000;
                }
            } catch (Exception e) {

            }
            try {
                if (totalsharestock != 0.0 && newprice != 0.0) {
                    mv = totalsharestock * newprice;
                }
            } catch (Exception e) {

            }
            double pe = 0.0;
            try {
                pe=getpe(jo2.getDouble("n_income_attr_p"),jo2.getString("end_date").substring(4,8),mv);
            } catch (Exception e) {

            }
            nc.setNewprice(newprice);
            nc.setMoney(money);
            nc.setZdlimit(zdlimit);
            nc.setQrr(qrr);
            nc.setHandchange(handchange);
            nc.setPe(pe);
        }

    }
    private double  getpe(double income,String time,double mv){
        double seasonincome=income/ SeasonEnum.getSeason(time)*4;
        return   mv/seasonincome;
    }

}

